package org.x.user.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.CollectionUtils;
import org.x.common.web.exception.BusinessException;
import org.x.user.entity.*;
import org.x.user.mapper.*;
import org.x.user.mapper.SysUserRolesMapper;

import java.lang.Boolean;
import java.lang.Override;
import java.lang.String;
import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.x.user.dto.UserDTO;
import org.x.user.service.UserService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.x.user.vo.UserVO;

import java.util.stream.Collectors;

import static org.x.common.base.result.ResultCode.USER_NAME_EXIST;
import static org.x.common.base.result.ResultCode.USER_NOT_FOUND;

/**
 * 用户管理的实现
 *
 * @author 夏包包
 * @date 2025-03-08 13:39:03
 */
@Service
public class UserServiceImpl extends ServiceImpl<SysUsersMapper, SysUsers> implements UserService {

    @Autowired
    private  SysUsersMapper userMapper;
    @Autowired
    private  SysUserDeptMapper userDeptMapper;
    @Autowired
    private  SysDeptMapper deptMapper;
    @Autowired
    private  SysUserRolesMapper userRolesMapper;
    @Autowired
    private  SysRoleMapper roleMapper;
    @Autowired
    private  SysRolePermMapper rolePermMapper;
    @Autowired
    private  SysPermMapper permMapper;
    @Autowired
    private  SysMenuMapper menuMapper;

    @Override
    public Boolean addUser(UserDTO userDTO) {
        // 检查用户名是否已存在
        QueryWrapper<SysUsers> wrapper = Wrappers.query();
        wrapper.eq("username", userDTO.getUsername());
        List<SysUsers> userDOList = userMapper.selectList(wrapper);
        if (!userDOList.isEmpty()) {
            // 用户名已存在
            throw new BusinessException(USER_NAME_EXIST);
        }
        // 将用户数据保存到数据库
        SysUsers userDO = new SysUsers();
        userDO.setId(userDTO.getUserId());
        userDO.setUsername(userDTO.getUsername());
        userDO.setPassword(userDTO.getPassword());
        userDO.setUserDesc(userDTO.getUserDesc());
        userDO.setTenantId(userDTO.getTenantId());
        userDO.setNickName(userDTO.getNickName());
        userDO.setEmail(userDTO.getEmail());
        userDO.setPhone(userDTO.getPhone());
        userDO.setStatus(userDTO.getStatus());
        userDO.setMainDeptId(userDTO.getMainDeptId());
        userDO.setLocale(userDTO.getLocale());
        // 示例创建人
        userDO.setCreateBy("admin");
        // 创建时间
        userDO.setCreateTime(new Date());
        int result = userMapper.insert(userDO);
        return result > 0;
    }

    @Override
    public Boolean deleteUser(UserDTO userDTO) {
        // 检查用户信息是否存在
        SysUsers userDO = userMapper.selectById(userDTO.getUserId());
        if (userDO == null) {
            // 用户信息不存在
            throw new BusinessException(USER_NOT_FOUND);
        }
        // 删除用户信息
        int result = userMapper.deleteById(userDTO.getUserId());
        return result > 0;
    }

    @Override
    public Boolean updateUser(UserDTO userDTO) {
        // 检查用户信息是否存在
        SysUsers userDO = userMapper.selectById(userDTO.getUserId());
        if (userDO == null) {
            throw new BusinessException(USER_NOT_FOUND);
        }
        // 检查用户名是否已存在且不为自身
        QueryWrapper<SysUsers> wrapper = Wrappers.query();
        wrapper.eq("username", userDTO.getUsername()).ne("id", userDTO.getUserId());
        List<SysUsers> existingUserList = userMapper.selectList(wrapper);
        if (!existingUserList.isEmpty()) {
            // 用户名已存在
            throw new BusinessException(USER_NAME_EXIST);
        }
        // 更新用户信息
        userDO.setUsername(userDTO.getUsername());
        userDO.setPassword(userDTO.getPassword());
        userDO.setUserDesc(userDTO.getUserDesc());
        userDO.setTenantId(userDTO.getTenantId());
        userDO.setNickName(userDTO.getNickName());
        userDO.setEmail(userDTO.getEmail());
        userDO.setPhone(userDTO.getPhone());
        userDO.setStatus(userDTO.getStatus());
        userDO.setMainDeptId(userDTO.getMainDeptId());
        userDO.setLocale(userDTO.getLocale());
        // 示例修改人
        userDO.setUpdateBy("admin");
        // 修改时间
        userDO.setUpdateTime(new Date());
        int result = userMapper.updateById(userDO);
        return result > 0;
    }

    @Override
    public UserVO userInfo(String userId) {
        // 检查用户信息是否存在
        UserVO dto = new UserVO();

        // 1. 查询基础用户信息
        SysUsers user = userMapper.selectById(userId);
        if (user == null) return null;
        dto.setUser(user);

        // 2. 查询角色信息
        List<SysUserRoles> userRoles = userRolesMapper.selectList(
                new QueryWrapper<SysUserRoles>().eq("user_id", userId)
        );
        if (!CollectionUtils.isEmpty(userRoles)) {
            List<String> roleIds = userRoles.stream()
                    .map(SysUserRoles::getRoleId)
                    .collect(Collectors.toList());

            dto.setRoles(roleMapper.selectBatchIds(roleIds));
        }

        // 3. 查询权限信息（基于角色）
        if (!CollectionUtils.isEmpty(dto.getRoles())) {
            List<String> roleIds = dto.getRoles().stream()
                    .map(SysRole::getId)
                    .collect(Collectors.toList());

            List<SysRolePerm> rolePerms = rolePermMapper.selectList(
                    new QueryWrapper<SysRolePerm>().in("role_id", roleIds)
            );

            if (!CollectionUtils.isEmpty(rolePerms)) {
                List<String> permIds = rolePerms.stream()
                        .map(SysRolePerm::getPermId)
                        .distinct()
                        .collect(Collectors.toList());

                dto.setPermissions(permMapper.selectBatchIds(permIds));
            }
        }

        // 4.2 所有关联部门
        List<SysUserDept> userDepts = userDeptMapper.selectList(
                new QueryWrapper<SysUserDept>().eq("user_id", userId)
        );
        if (!CollectionUtils.isEmpty(userDepts)) {
            List<String> deptIds = userDepts.stream()
                    .map(SysUserDept::getDeptId)
                    .collect(Collectors.toList());

            dto.setAllDepts(deptMapper.selectBatchIds(deptIds));
        }

        // 5. 查询菜单信息（新增部分）
        if (!CollectionUtils.isEmpty(dto.getPermissions())) {
            // 获取所有权限ID
            Set<String> permIds = dto.getPermissions().stream()
                    .map(SysPerm::getId)
                    .collect(Collectors.toSet());

            // 查询直接关联的菜单
            List<SysMenu> menus = menuMapper.selectList(
                    new QueryWrapper<SysMenu>()
                            .in("perm_id", permIds)
                            .orderByAsc("sort")
            );

            // 构建菜单树
            dto.setMenuTree(buildMenuTree(menus,"0"));
        }

        return dto;

    }

    @Override
    public List<SysUserDept> userDept(String userId) {
        // 查询用户部门关系
        QueryWrapper<SysUserDept> wrapper = Wrappers.query();
        wrapper.eq("user_id", userId);
        List<SysUserDept> userDeptList = userMapper.selectUserDeptList(wrapper);
        return userDeptList;
    }

    @Override
    public List<SysUserRoles> userRoles(String userId) {
        // 查询用户角色分配
        QueryWrapper<SysUserRoles> wrapper = Wrappers.query();
        wrapper.eq("user_id", userId);
        List<SysUserRoles> userRoleList = userMapper.selectUserRoleList(wrapper);
        return userRoleList;
    }

    @Override
    public List<SysTokens> userTokens(String userId) {
        // 查询用户令牌信息
        QueryWrapper<SysTokens> wrapper = Wrappers.query();
        wrapper.eq("user_id", userId);
        List<SysTokens> userTokenList = userMapper.selectUserTokenList(wrapper);
        return userTokenList;
    }

    // 新增菜单树构建方法
    private List<UserVO.MenuNode> buildMenuTree(List<SysMenu> menus, String parentId) {
        return menus.stream()
                .filter(menu -> parentId.equals(menu.getParentId()))
                .map(menu -> {
                    UserVO.MenuNode node = new UserVO.MenuNode();
                    node.setMenu(menu);
                    node.setChildren(buildMenuTree(menus, menu.getId()));
                    return node;
                })
                .collect(Collectors.toList());
    }


}
